package cn.vihub.service.impl;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import cn.vihub.handler.MyRuntimeException;
import cn.vihub.param.ShopGoodsParam;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import cn.vihub.param.ShopOrderGoodsParam;
import cn.vihub.param.ShopOrderParam;
import cn.vihub.pojo.ShopOrderGoods;
import cn.vihub.service.ShopOrderGoodsService;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import com.alibaba.fastjson2.JSON;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.vihub.mapper.ShopOrderMapper;
import cn.vihub.pojo.ShopOrder;
import cn.vihub.service.ShopOrderService;
import org.springframework.transaction.annotation.Transactional;

/**
 * @Author: 秋晚
 * @Date:  2025/8/7 20:24
 * @Description: 
 **/

@Service
public class ShopOrderServiceImpl extends ServiceImpl<ShopOrderMapper, ShopOrder> implements ShopOrderService{

    @Autowired
    ShopOrderGoodsService shopOrderGoodsService;

   @Autowired
   private StringRedisTemplate redisTemplate;

   @Autowired
   RabbitTemplate rabbitTemplate;

    @Override
    @Transactional
    public Boolean add(ShopOrderParam shopOrderParam) {
        // 生成订单号（时间方式）
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
//        String format = sdf.format(new Date());
//        String orderNumber="JD"+format+ RandomUtil.randomNumbers(4);
        //生成订单号  使用雪花算法
        Snowflake snowflake = IdUtil.getSnowflake(1, 1);
        String orderNumber="JD"+snowflake.nextIdStr();

        //初始化订单数据   (拷贝赋值)
        ShopOrder shopOrder = new ShopOrder();
        BeanUtils.copyProperties(shopOrderParam,shopOrder);
        //初始化订单号
        shopOrder.setOrderNumber(orderNumber);
        //初始化下单时间
        shopOrder.setStartTime(new Date());
        //初始化创建人和创建时间
        shopOrder.setCreateBy(shopOrderParam.getMemberId().toString());

        //初始化更新人和更新时间
        shopOrder.setUpdateBy(shopOrderParam.getMemberId().toString());
        shopOrder.setUpdateTime(new Date());
        //添加订单记录
        save(shopOrder);
        //定义一个集合存储订单商品   (遍历原本集合 然后进行拷贝赋值)
        ArrayList<ShopOrderGoods> shopOrderGoods = new ArrayList<>();
        for (ShopOrderGoodsParam shopOrderGoodsParam : shopOrderParam.getOrderGoodsParamList()) {
            //拷贝赋值
            ShopOrderGoods orderGoods = new ShopOrderGoods();
            BeanUtils.copyProperties(shopOrderGoodsParam,orderGoods);
            orderGoods.setOrderNumber(orderNumber);
            orderGoods.setUpdateBy(shopOrderParam.getMemberId());
            orderGoods.setUpdateTime(new Date());
            orderGoods.setCreateBy(shopOrderParam.getMemberId());
            orderGoods.setCreateTime(new Date());
            shopOrderGoods.add(orderGoods);
        }

        //批量添加商品记录关联表里的记录
        shopOrderGoodsService.saveBatch(shopOrderGoods);
        return true;
    }

    @Override
    public Boolean addOne(ShopOrderParam shopOrderParam) {
        //设置随机UUID和锁
        String lockKey="goodsId:1";
        String lockUUID= UUID.randomUUID().toString();

        //上锁
        Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent(lockKey, lockUUID, 10, TimeUnit.SECONDS);
        if(!aBoolean){
            //有人正在抢购
            throw new MyRuntimeException("请稍后再试,此时人数过多!");
        }


        //提前占用库存
        Long decrement = redisTemplate.opsForValue().decrement("goodsId1");
        if(decrement<0){
            //回退
            redisTemplate.opsForValue().increment("goodsId1");
            throw new MyRuntimeException("库存已经没了!!!!");
        }


        //把信息存入redis(此时redis就是一个消息队列)
        redisTemplate.opsForList().leftPush("orderGoods",JSON.toJSONString(shopOrderParam));


        //释放锁        //判断这个锁是不是之前上的锁
        String s = redisTemplate.opsForValue().get(lockKey);
        if(!s.equals(lockUUID)){
            throw new MyRuntimeException("不是你的,稍等!");
        }
        //释放锁
        redisTemplate.delete(lockKey);
        return true;
    }

    @Scheduled(cron = "0/10 * * * * ?")
    public void taskTime(){
        String orderGoods = redisTemplate.opsForList().rightPop("orderGoods");
        if(orderGoods==null){
            return;
        }

        ShopOrderParam shopOrderParam = JSON.parseObject(orderGoods, ShopOrderParam.class);
        //生成订单号  使用雪花算法
        Snowflake snowflake = IdUtil.getSnowflake(1, 1);
        String orderNumber="JD"+snowflake.nextIdStr();

        //初始化订单数据   (拷贝赋值)
        ShopOrder shopOrder = new ShopOrder();
        BeanUtils.copyProperties(shopOrderParam,shopOrder);
        //初始化订单号
        shopOrder.setOrderNumber(orderNumber);
        //初始化下单时间
        shopOrder.setStartTime(new Date());
        //初始化创建人和创建时间
        shopOrder.setCreateBy(shopOrderParam.getMemberId().toString());

        //初始化更新人和更新时间
        shopOrder.setUpdateBy(shopOrderParam.getMemberId().toString());
        shopOrder.setUpdateTime(new Date());
        //添加订单记录
        save(shopOrder);
        //定义一个集合存储订单商品   (遍历原本集合 然后进行拷贝赋值)
        ArrayList<ShopOrderGoods> shopOrderGoods = new ArrayList<>();
        for (ShopOrderGoodsParam shopOrderGoodsParam : shopOrderParam.getOrderGoodsParamList()) {
            //拷贝赋值
            ShopOrderGoods orderGood = new ShopOrderGoods();
            BeanUtils.copyProperties(shopOrderGoodsParam,orderGood);
            orderGood.setOrderNumber(orderNumber);
            orderGood.setOrderNumber(orderNumber);
            orderGood.setUpdateBy(shopOrderParam.getMemberId());
            orderGood.setUpdateTime(new Date());
            orderGood.setCreateBy(shopOrderParam.getMemberId());
            orderGood.setCreateTime(new Date());
            shopOrderGoods.add(orderGood);
        }

        //批量添加商品记录关联表里的记录
        shopOrderGoodsService.saveBatch(shopOrderGoods);

//        //存入rabbitmq进行等待支付
//        rabbitTemplate.convertAndSend(
//                "GoodsOrderDelayedMessage",   //延迟交换机名称
//                "goods.order.key",//路由键
//                orderNumber,//消息内容
//                message -> {  //消息后置处理器 (设置延迟参数)
//                    //设置延迟时间  2分钟  2*60*1000
//                    message.getMessageProperties().setHeader("x-delay",120000);
//                    return message;
//                }
//        );
    }
}
